﻿using System;
using System.Collections;
using System.Collections.Generic;
using Game.UiState;
using UnityEngine;

/// <summary>
/// 游戏管理器组件
/// </summary>
public class Manager : MonoBehaviour
{
    /// <summary>
    /// 标题视图
    /// </summary>
    public GameObject TitleView;

    /// <summary>
    /// 游戏视图
    /// </summary>
    public GameObject GameView;

    /// <summary>
    /// 提示信息视图
    /// </summary>
    public GameObject TipsView;

    /// <summary>
    /// Ui 状态接口
    /// </summary>
    public interface IUiState
    {
        /// <summary>
        /// 进入状态时的回调
        /// </summary>
        void OnEnter();

        /// <summary>
        /// 每帧更新时的回调
        /// </summary>
        void OnUpdate();

        /// <summary>
        /// 退出状态时的回调
        /// </summary>
        void OnExit();
    }

    /// <summary>
    /// 当前的 Ui 状态
    /// </summary>
    private IUiState _CurrentUiState;

    /// <summary>
    /// 已经入栈的 Ui 状态
    /// </summary>
    private Stack<IUiState> _StackedUiState;

    /// <summary>
    /// 外部可访问单例
    /// </summary>
    public static Manager Instance { get; protected set; }

    // Start is called before the first frame update
    void Start()
    {
        Instance = this;
        _StackedUiState = new Stack<IUiState>();
        ChangeUiState(new TitleState());
    }

    void Update()
    {
        if (_CurrentUiState != null)
            _CurrentUiState.OnUpdate();
    }

    /// <summary>
    /// 改变 Ui 状态
    /// </summary>
    /// <param name="newState">新状态</param>
    public void ChangeUiState(IUiState newState)
    {
        if (_CurrentUiState != null)
            _CurrentUiState.OnExit();
        _CurrentUiState = newState;
        if (_CurrentUiState != null)
            _CurrentUiState.OnEnter();
    }

    /// <summary>
    /// 改变 Ui 状态
    /// </summary>
    /// <param name="newStateName">新状态名</param>
    public void ChangeUiState(string newStateName)
    {
        ChangeUiState(CreateUiStateByName(newStateName));
    }

    /// <summary>
    /// 把当前 Ui 状态入栈，并改变 Ui 状态
    /// </summary>
    /// <param name="newState">新状态</param>
    public void PushUiState(IUiState newState)
    {
        if (_CurrentUiState != null)
            _StackedUiState.Push(_CurrentUiState);
        ChangeUiState(newState);
    }

    /// <summary>
    /// 把当前 Ui 状态入栈，并改变 Ui 状态
    /// </summary>
    /// <param name="stateName">新状态名</param>
    public void PushUiState(string stateName)
    {
        PushUiState(CreateUiStateByName(stateName));
    }

    /// <summary>
    /// 将存储在栈顶的 Ui 状态弹出并设为当前状态
    /// </summary>
    public void PopUiState()
    {
        if (_StackedUiState.Count > 0)
            ChangeUiState(_StackedUiState.Pop());
    }

    /// <summary>
    /// 根据命名创建 Ui 状态
    /// </summary>
    /// <param name="stateName">状态名</param>
    /// <returns></returns>
    private IUiState CreateUiStateByName(string stateName)
    {
        switch (stateName)
        {
            case "Title": return new TitleState();
            case "Game": return new GameState();
            case "SimpleTips": return new SimpleTipsState();
        }
        return null;
    }
}
